/**
 *
 */
package jp.seraph.cui;

import java.util.ArrayList;
import java.util.List;

import jp.seraph.cui.message.MessageUtil;

import org.apache.commons.lang.ArrayUtils;

/**
 *
 *
 */
public class DefaultConsole implements InternalConsole, ExternalConsole {
    public DefaultConsole(ConsoleContext aContext) {
        mContext = aContext;
        mListeners = new ArrayList<ConsoleListener>();
    }

    public void setContext(ConsoleContext aContext) {
        mContext = aContext;
    }

    private ConsoleContext mContext;
    private List<ConsoleListener> mListeners;
    private final String SEPARATOR = "/";

    /**
     *
     * @see jp.seraph.cui.InternalConsole#getContext()
     */
    public ConsoleContext getContext() {
        return mContext;
    }

    /**
     *
     * @see jp.seraph.cui.InternalConsole#output(java.lang.String)
     */
    public void output(String aMessage) {
        fireConsoleEvent(aMessage);
    }

    /**
     *
     * @see jp.seraph.cui.ExternalConsole#addConsoleListener(jp.seraph.cui.ConsoleListener)
     */
    public void addConsoleListener(ConsoleListener aListener) {
        mListeners.add(aListener);
    }

    /**
     *
     * @see jp.seraph.cui.ExternalConsole#input(java.lang.String)
     */
    public void input(String aCommand) {
        String[] tParameters = aCommand.split("\\s+");
        int tLength = tParameters.length;
        SystemNode[] tNodes = null;
        tNodes = new SystemNode[tLength];

        for (int i = 0; i < tLength; i++) {
            String tParameter = tParameters[i];
            if (tParameter.matches("\".+\"")) {
                tNodes[i] = new StringData(tParameter.substring(1, tParameter.length() - 1), mContext.getMode(), this);
            } else {
                tNodes[i] = CuiSystemUtil.resolvePath(this.getContext(), tParameter, SEPARATOR);
            }
        }

        if (!tNodes[0].getType().isCommand())
            throw new IllegalArgumentException(MessageUtil.cannotExecuteError(CuiSystemUtil.getFullPath(tNodes[0], SEPARATOR)));

        ((Command) tNodes[0]).execute((SystemNode[]) ArrayUtils.subarray(tNodes, 1, tNodes.length));
    }

    /**
     *
     * @see jp.seraph.cui.ExternalConsole#removeConsoleListener(jp.seraph.cui.ConsoleListener)
     */
    public void removeConsoleListener(ConsoleListener aListener) {
        mListeners.remove(aListener);
    }

    public void fireConsoleEvent(String aMessage) {
        for (ConsoleListener tListener : mListeners) {
            tListener.listen(aMessage);
        }
    }

}
